package com.ibeeking.found.cop.b.rest.service.mq;

import com.ibeeking.found.cop.b.rest.service.IFriendsService;
import com.ibeeking.found.cop.b.rest.service.IFriendsTagsGroupService;
import com.ibeeking.found.cop.b.rest.service.IFriendsTagsService;
import com.ibeeking.found.cop.b.rest.service.IWxOpenService;
import com.ibeeking.found.cop.b.rest.wechat.WxCpFollowUserList;
import com.ibeeking.found.cop.service.common.bo.FollowedUserTagBO;
import com.ibeeking.found.cop.service.common.bo.FriendsExternalAttrBO;
import com.ibeeking.found.cop.service.common.bo.FriendsExternalProfileBO;
import com.ibeeking.found.cop.service.common.bo.FriendsWechatChannelBO;
import com.ibeeking.found.cop.service.common.param.*;
import com.ibeeking.found.cop.service.mapper.CopEmployeeMapper;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.log.utils.LogUtils;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.data.StringUtils;
import com.ibeeking.nematos.utils.date.DateUtil;
import com.ibeeking.nematos.utils.json.JsonUtils;
import me.chanjar.weixin.common.enums.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.error.WxRuntimeException;
import me.chanjar.weixin.cp.api.WxCpExternalContactService;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
import me.chanjar.weixin.cp.bean.external.WxCpUserExternalTagGroupList;
import me.chanjar.weixin.cp.bean.external.contact.ExternalContact;
import me.chanjar.weixin.cp.bean.external.contact.FollowedUser;
import me.chanjar.weixin.cp.bean.external.contact.WxCpExternalContactBatchInfo;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Service
public class CopFriendsMqConsumerHandler {

    @Resource
    private IFriendsService friendsServiceImpl;

    @Resource
    private IFriendsTagsGroupService friendsTagsGroupServiceImpl;

    @Resource
    private IFriendsTagsService friendsTagsServiceImpl;

    @Resource
    private CopEmployeeMapper copEmployeeMapper;

    @Resource
    private IWxOpenService wxOpenServiceImpl;


    public boolean syncFriendsTagsFromWxcp(MqSyncCopParam mqParam, Map<String, Object> extMap) {
        try {
            Long tenantId = mqParam.getTenantId();
            WxCpService wxCpService = wxOpenServiceImpl.getWxCpService(tenantId);
            WxCpConfigStorage wxCpConfigStorage = wxCpService.getWxCpConfigStorage();
            if (wxCpConfigStorage == null) {
                throw new BusinessException("获取企微服务失败!");
            }
            String corpId = wxCpConfigStorage.getCorpId();

            WxCpExternalContactService wxCpExternalContactService = wxCpService.getExternalContactService();
            if (wxCpExternalContactService == null) throw new BusinessException("获取企微服务外部联系人服务!");

            WxCpUserExternalTagGroupList wxCpUserExternalTagGroupList = wxCpExternalContactService.getCorpTagList(null, null);
            if(wxCpUserExternalTagGroupList !=null){
                List<WxCpUserExternalTagGroupList.TagGroup> tagGroupList = wxCpUserExternalTagGroupList.getTagGroupList();
                if(Collections3.isNotEmpty(tagGroupList)){
                    List<FriendsTagsGroupParam> tagsTypeParamList = new ArrayList<>();
                    for(WxCpUserExternalTagGroupList.TagGroup tagGroup: tagGroupList){
                        FriendsTagsGroupParam tagsTypeParam = new FriendsTagsGroupParam();
                        tagsTypeParam.setGroupCode(tagGroup.getGroupId());
                        tagsTypeParam.setGroupName(tagGroup.getGroupName());
                        tagsTypeParam.setSort(tagGroup.getOrder());
                        if(tagGroup.getCreateTime() != null) {
                            LocalDateTime buildTime = DateUtil.longToLocalDateTime(tagGroup.getCreateTime());
                            tagsTypeParam.setBuildTime(DateUtil.localDateTimeToStr(buildTime));
                        }
                        if(tagGroup.getDeleted() != null) {
                            tagsTypeParam.setDelStatus(tagGroup.getDeleted() ? 1 : 0);
                        }else{
                            tagsTypeParam.setDelStatus(0);
                        }

                        List<WxCpUserExternalTagGroupList.TagGroup.Tag> tagsList = tagGroup.getTag();
                        List<FriendsTagsParam> tagsParamList = new ArrayList<>();
                        if(Collections3.isNotEmpty(tagsList)){
                            for(WxCpUserExternalTagGroupList.TagGroup.Tag friednsTag: tagsList){
                                FriendsTagsParam tagsParam= new FriendsTagsParam();
                                tagsParam.setTagsCode(friednsTag.getId());
                                tagsParam.setTagsName(friednsTag.getName());
                                tagsParam.setSort(friednsTag.getOrder());
                                if(friednsTag.getCreateTime() != null) {
                                    LocalDateTime buildTime = DateUtil.longToLocalDateTime(friednsTag.getCreateTime());
                                    tagsParam.setBuildTime(DateUtil.localDateTimeToStr(buildTime));
                                }
                                if(friednsTag.getDeleted() != null) {
                                    tagsParam.setDelStatus(friednsTag.getDeleted() ? 1 : 0);
                                }else{
                                    tagsParam.setDelStatus(0);
                                }
                                tagsParamList.add(tagsParam);
                            }
                        }
                        tagsTypeParam.setTagsList(tagsParamList);
                        tagsTypeParamList.add(tagsTypeParam);
                    }
                    LogUtils.info("====tagsTypeParamList:{}====", JsonUtils.toJsonStr(tagsTypeParamList));
                    if(Collections3.isNotEmpty(tagsTypeParamList)){
                        friendsTagsServiceImpl.saveOrUpdateOrDeleteBatchFriendsTags(tenantId, tagsTypeParamList);
                    }
                }
            }
            return true;
        } catch (Exception e) {
            LogUtils.error("同步客户标签任务处理异常:{}", e);
            return false;
        }
    }

    public boolean addAndUpdateFriendsTags(MqSyncCopParam mqParam, Map<String, Object> extMap) {
        Long tenantId = mqParam.getTenantId();
        Long msgId = mqParam.getId();
        String operType= mqParam.getOperType();
        friendsTagsGroupServiceImpl.syncFriendsTagsToWxCp(tenantId.intValue(), msgId, false);
        return true;
    }
    public boolean delFriendsTags(MqSyncCopParam mqParam, Map<String, Object> extMap) {
        Long tenantId = mqParam.getTenantId();
        Long msgId = mqParam.getId();
        String operType= mqParam.getOperType();
        friendsTagsGroupServiceImpl.syncFriendsTagsToWxCp(tenantId.intValue(), msgId, true);
        return true;
    }

    public boolean syncFriendsFromWxcp(MqSyncCopParam mqParam, Map<String, Object> extMap) {
        try {
            Long tenantId = mqParam.getTenantId();
            WxCpService wxCpService = wxOpenServiceImpl.getWxCpService(tenantId);
            WxCpConfigStorage wxCpConfigStorage = wxCpService.getWxCpConfigStorage();
            if (wxCpConfigStorage == null) {
                throw new BusinessException("获取企微服务失败!");
            }
            String corpId = wxCpConfigStorage.getCorpId();

            WxCpExternalContactService wxCpExternalContactService = wxCpService.getExternalContactService();
            if (wxCpExternalContactService == null) throw new BusinessException("获取企微服务外部联系人服务!");

            List<String> rightEmployeeList = getHaveFollowRightUserList(tenantId.toString());

            if(Collections3.isNotEmpty(rightEmployeeList)) {
                String nextCursor = null;
                List<FriendsParam> allFriendsParams = new ArrayList<>();
                String[] rightEmployeeArray = new String[rightEmployeeList.size()];
                rightEmployeeArray = rightEmployeeList.toArray(rightEmployeeArray);
                do {
                    WxCpExternalContactBatchInfo wxCpExternalContactBatchInfo = wxCpExternalContactService.getContactDetailBatch(rightEmployeeArray, nextCursor, 90);

                    if (wxCpExternalContactBatchInfo != null) {
                        nextCursor = wxCpExternalContactBatchInfo.getNextCursor();
                        List<WxCpExternalContactBatchInfo.ExternalContactInfo> externalContactInfoList = wxCpExternalContactBatchInfo.getExternalContactList();

                        if (Collections3.isNotEmpty(externalContactInfoList)) {
                            externalContactInfoList.parallelStream().forEach(d -> {
                                ExternalContact externalContact = d.getExternalContact();
                                if (externalContact != null) {
                                    FriendsParam friendsParam = new FriendsParam();
                                    String friendsCode = externalContact.getExternalUserId();
                                    friendsParam.setFriendsCode(friendsCode);
                                    friendsParam.setGender(externalContact.getGender());
                                    friendsParam.setName(externalContact.getName());
                                    friendsParam.setNickname(externalContact.getNickname());
                                    friendsParam.setAvatarUrl(externalContact.getAvatar());
                                    friendsParam.setPosition(externalContact.getPosition());
                                    friendsParam.setCorpName(externalContact.getCorpName());
                                    friendsParam.setCorpFullName(externalContact.getCorpFullName());
                                    friendsParam.setUnionid(externalContact.getUnionId());
                                    friendsParam.setType(externalContact.getType());

                                    ExternalContact.ExternalProfile externalContactProfile = externalContact.getExternalProfile();
                                    if (externalContactProfile != null) {
                                        FriendsExternalProfileBO externalProfile = new FriendsExternalProfileBO();
                                        externalProfile.setExternalCorpName(externalContactProfile.getExternalCorpName());
                                        List<ExternalContact.ExternalAttribute> externalAttribute = externalContactProfile.getExternalAttrs();
                                        if (Collections3.isNotEmpty(externalAttribute)) {
                                            List<FriendsExternalAttrBO> externalAttrs = new ArrayList<>();
                                            externalAttribute.parallelStream().forEach(s -> {
                                                FriendsExternalAttrBO externalAttr = new FriendsExternalAttrBO();
                                                externalAttr.setFriendsCode(friendsCode);
                                                externalAttr.setType(s.getType());
                                                ExternalContact.ExternalAttribute.Text externalAttributeText = s.getText();
                                                if (externalAttributeText != null) {
                                                    externalAttr.setName(s.getName());
                                                    externalAttr.setValue(externalAttributeText.getValue());
                                                }
                                                ExternalContact.ExternalAttribute.Web externalAttributeWeb = s.getWeb();
                                                if (externalAttributeWeb != null) {
                                                    externalAttr.setTitle(externalAttributeWeb.getTitle());
                                                    externalAttr.setUrl(externalAttributeWeb.getUrl());
                                                }
                                                ExternalContact.ExternalAttribute.MiniProgram externalAttributeMiniProgram = s.getMiniProgram();
                                                if (externalAttributeMiniProgram != null) {
                                                    externalAttr.setTitle(externalAttributeMiniProgram.getTitle());
                                                    externalAttr.setAppid(externalAttributeMiniProgram.getAppid());
                                                    externalAttr.setPagePath(externalAttributeMiniProgram.getPagePath());
                                                }
                                                externalAttrs.add(externalAttr);
                                            });
                                            externalProfile.setExternalAttrs(externalAttrs);
                                        }
                                        ExternalContact.WechatChannel externalWechatChannel = externalContactProfile.getWechatChannels();
                                        if (externalWechatChannel != null) {
                                            FriendsWechatChannelBO wechatChannel = new FriendsWechatChannelBO();
                                            wechatChannel.setFriendsCode(friendsCode);
                                            wechatChannel.setNickname(externalWechatChannel.getNickname());
                                            wechatChannel.setStatus(externalWechatChannel.getStatus());
                                            externalProfile.setWechatChannel(wechatChannel);
                                        }
                                        friendsParam.setExternalProfileBO(externalProfile);
                                    }
                                    FollowedUser followedUser = d.getFollowInfo();
                                    if (followedUser != null) {
                                        List<FriendsFollowParam> allFriendsFollowParams = new ArrayList<>();
                                        FriendsFollowParam friendsFollowParam = new FriendsFollowParam();
                                        friendsFollowParam.setFriendsCode(friendsCode);
                                        friendsFollowParam.setFriendsName(externalContact.getName());
                                        friendsFollowParam.setEmployeeCode(followedUser.getUserId());
                                        friendsParam.setEmployeeCode(followedUser.getUserId());
                                        friendsFollowParam.setDescription(followedUser.getDescription());
                                        if (followedUser.getCreateTime() != null) {
                                            LocalDateTime buildTime = DateUtil.longToLocalDateTime(followedUser.getCreateTime());
                                            friendsFollowParam.setBuildTime(DateUtil.localDateTimeToStr(buildTime));
                                            friendsParam.setJoinTime(DateUtil.localDateTimeToStr(buildTime));
                                        }
                                        friendsFollowParam.setOperatorId(followedUser.getOperatorUserId());
                                        friendsFollowParam.setRemark(followedUser.getRemark());
                                        friendsParam.setRemark(followedUser.getRemark());
                                        friendsFollowParam.setRemarkCompany(followedUser.getRemarkCompany());
                                        friendsFollowParam.setRemarkCorpName(followedUser.getRemarkCorpName());
                                        if (StringUtils.isNotEmpty(followedUser.getAddWay())) {
                                            friendsFollowParam.setSourceFrom(Integer.valueOf(followedUser.getAddWay()));
                                            friendsParam.setSourceFrom(Integer.valueOf(followedUser.getAddWay()));
                                        }
                                        friendsFollowParam.setState(followedUser.getState());
                                        String[] remarkMobilesArr = followedUser.getRemarkMobiles();
                                        if (remarkMobilesArr != null && remarkMobilesArr.length > 0) {
                                            List<String> trasRemarkMobilesList = Arrays.asList(remarkMobilesArr);
                                            friendsFollowParam.setRemarkMobilesJson(JsonUtils.toJsonStr(trasRemarkMobilesList));
                                            friendsParam.setMobile(JsonUtils.toJsonStr(trasRemarkMobilesList));
                                        } else {
                                            friendsFollowParam.setRemarkMobilesJson(null);
                                        }
                                        String[] tagIdsArr = followedUser.getTagIds();
                                        if (tagIdsArr != null && tagIdsArr.length > 0) {
                                            List<String> trasTagIdsList = Arrays.asList(tagIdsArr);
                                            friendsFollowParam.setRemarkTagIdsJson(JsonUtils.toJsonStr(trasTagIdsList));
                                        } else {
                                            friendsFollowParam.setRemarkTagIdsJson(null);
                                        }
                                        FollowedUser.Tag[] followedUserTags = followedUser.getTags();
                                        if (followedUserTags != null && followedUserTags.length > 0) {
                                            List<FollowedUserTagBO> followedUserTagBOList = new ArrayList<>();
                                            for (FollowedUser.Tag followedUserTag : followedUserTags) {
                                                FollowedUserTagBO userTagBO = BeanUtil.convertBean(followedUserTag, FollowedUserTagBO.class);
                                                followedUserTagBOList.add(userTagBO);
                                            }
                                            friendsFollowParam.setFollowedUserTagList(followedUserTagBOList);
                                        }
                                        allFriendsFollowParams.add(friendsFollowParam);
                                        friendsParam.setFriendsFollowList(allFriendsFollowParams);
                                    }
                                    allFriendsParams.add(friendsParam);
                                }
                            });
                        }
                    }
                }while(nextCursor == null);
                LogUtils.info("====allFriendsParams:{}====", JsonUtils.toJsonStr(allFriendsParams));
                if(Collections3.isNotEmpty(allFriendsParams)){
                    friendsServiceImpl.saveOrUpdateOrDeleteBatchFriends(tenantId, allFriendsParams);
                }
            }
            return true;
        } catch (Exception e) {
            LogUtils.error("同步客户信息任务处理异常:{}", e);
            return false;
        }
    }

    private List<String> getHaveFollowRightUserList(String tenantId){
        try {
            String getFollowUserUrl = "/cgi-bin/externalcontact/get_follow_user_list?access_token=%s";
            WxCpServiceImpl wxCpService = (WxCpServiceImpl)wxOpenServiceImpl.getWxCpService(Long.valueOf(tenantId));
            WxCpConfigStorage wxCpConfigStorage = wxCpService.getWxCpConfigStorage();
            if (wxCpConfigStorage == null) {
                throw new BusinessException("获取企微服务失败!");
            }

            String url = String.format(wxCpConfigStorage.getApiUrl(getFollowUserUrl),wxCpConfigStorage.getAccessToken());
            try {
                HttpGet httpGet = new HttpGet(url);
                String resultContent;
                try (CloseableHttpClient httpClient = wxCpService.getRequestHttpClient();
                     CloseableHttpResponse response = httpClient.execute(httpGet)) {
                    resultContent = new BasicResponseHandler().handleResponse(response);
                } finally {
                    httpGet.releaseConnection();
                }
                WxError error = WxError.fromJson(resultContent, WxType.CP);
                if (error.getErrorCode() != 0) {
                    throw new WxErrorException(error);
                }
                LogUtils.info("====checkFollowUser:{}====", JsonUtils.toJsonStr(resultContent));
                WxCpFollowUserList accessToken = WxCpFollowUserList.fromJson(resultContent);
                LogUtils.info("====accessToken:{}====", JsonUtils.toJsonStr(accessToken));
                return accessToken.getFollowUser();
            } catch (IOException e) {
                throw new WxRuntimeException(e);
            }
        }catch(WxErrorException ex){
            return Collections3.emptyList();
        }
    }
}

